package com.symaster.common.swing.element.card;

import com.symaster.common.image.util.ImageUtil;
import com.symaster.common.swing.util.SwingUtil;
import com.symaster.common.util.IOUtil;
import org.apache.commons.lang3.StringUtils;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;

/**
 * @author yinmiao
 * @version 2022-08-16 19:04
 */
public class ImageCard extends JButton {

    private static final Font microsoft_yaHei = new Font("Microsoft YaHei", Font.PLAIN, 11);
    private BufferedImage cacheImage;
    private final Mat mat;

    public ImageCard() {

        InputStream inputStream = null;
        try {
            URL resource = SwingUtil.class.getResource("/icon/image.png");
            if (resource == null) {
                throw new RuntimeException("文件缺失");
            }
            inputStream = resource.openStream();
            mat = ImageUtil.toMat(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            IOUtil.close(inputStream);
        }
        initPage();
    }

    public ImageCard(File image) throws FileNotFoundException {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(image);
            mat = ImageUtil.toMat(fileInputStream);
        } finally {
            IOUtil.close(fileInputStream);
        }
        initPage();
    }

    public ImageCard(byte[] image) {
        mat = ImageUtil.toMat(image);
        initPage();
    }

    public ImageCard(InputStream image) {
        try {
            mat = ImageUtil.toMat(image);
        } finally {
            IOUtil.close(image);
        }
        initPage();
    }

    public ImageCard(String image) throws FileNotFoundException {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(image);
            mat = ImageUtil.toMat(fileInputStream);
        } finally {
            IOUtil.close(fileInputStream);
        }
        initPage();
    }

    public ImageCard(BufferedImage image) {
        if (BufferedImage.TYPE_3BYTE_BGR == image.getType()) {
            mat = ImageUtil.bufferedImageRGB2MatBGR(image);
        } else {
            mat = ImageUtil.bufferedImageRGBA2MatBGRA(image);
        }
        initPage();
    }

    public ImageCard(Mat image) {
        this.mat = image;
        initPage();
    }

    public ImageCard(File image, String text) throws IOException {
        super(text);

        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(image);
            mat = ImageUtil.toMat(fileInputStream);
        } finally {
            IOUtil.close(fileInputStream);
        }
        initPage();
    }

    public ImageCard(byte[] image, String text) {
        super(text);
        mat = ImageUtil.toMat(image);
        initPage();
    }

    public ImageCard(InputStream image, String text) {
        super(text);
        try {
            mat = ImageUtil.toMat(image);
        } finally {
            IOUtil.close(image);
        }
        initPage();
    }

    public ImageCard(String image, String text) throws FileNotFoundException {
        super(text);
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(image);
            mat = ImageUtil.toMat(fileInputStream);
        } finally {
            IOUtil.close(fileInputStream);
        }
        initPage();
    }

    public ImageCard(BufferedImage image, String text) {
        super(text);
        if (BufferedImage.TYPE_3BYTE_BGR == image.getType()) {
            mat = ImageUtil.bufferedImageRGB2MatBGR(image);
        } else {
            mat = ImageUtil.bufferedImageRGBA2MatBGRA(image);
        }
        initPage();
    }

    public ImageCard(Mat image, String text) {
        super(text);
        this.mat = image;
        initPage();
    }

    private void initPage() {
        this.setLayout(new BorderLayout());
        this.setBackground(UIManager.getColor("Panel.background"));
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        if (g instanceof Graphics2D) SwingUtil.antialiasingOn((Graphics2D) g);

        Rectangle bounds = g.getClipBounds();
        if (bounds.width <= 0 || bounds.height <= 0) return;

        Dimension size = getSize();
        int w = size.width - 2;
        int h = size.height - 2;
        if (cacheImage == null || cacheImage.getWidth() != w || cacheImage.getHeight() != h) {
            Mat bg = null;
            Mat cache1 = null;
            try {
                Color background = getBackground();
                bg = new Mat(new Size(w, h), mat.type(), new Scalar(background.getBlue(), background.getGreen(), background.getRed(), background.getAlpha()));

                cache1 = new Mat(mat.size(), mat.type());
                mat.copyTo(cache1);
                ImageUtil.scaleMat(cache1, Math.max(w, h));

                cacheImage = (BufferedImage) ImageUtil.toBufferedImage(bg);
            } finally {
                IOUtil.close(bg, cache1);
            }
        }

        g.drawImage(cacheImage, 1, 1, null);

        if (StringUtils.isNotEmpty(super.getText())) {
            int height = 20;
            int strY = 99;

            g.setColor(new Color(255, 255, 255, 140));
            g.fillRect(1, strY, bounds.width - 2, height);

            g.setColor(new Color(0, 0, 0, 255));
            g.setFont(microsoft_yaHei);
            g.drawString(super.getText(), 5, strY + 15);
        }
    }

    public static void main(String[] args) throws Exception {
        JFrame jFrame = new JFrame();
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new FlowLayout());
        ImageCard imageCard = new ImageCard("D:\\server-icon.jpg");
        imageCard.setPreferredSize(new Dimension(120, 120));
        jPanel.add(imageCard);
        jFrame.setContentPane(jPanel);
        jFrame.setPreferredSize(new Dimension(500, 500));
        jFrame.pack();
        jFrame.setVisible(true);


    }
}
